<template>
  <common-page
    class="report-add-page"
    :title="isEdit ? '编辑报表' : '新增报表'"
  >
    <el-button slot="header" @click="goBack">返回</el-button>
    <el-button
      slot="header"
      type="primary"
      @click="submit"
      :loading="isPersistenceLoading"
      >保存</el-button
    >

    <div class="report-add-page-main" slot="content">
      <div class="base-info-wrap">
        <common-group-title title="基本配置"></common-group-title>
        <el-form ref="form" :model="form" :rules="rules" label-width="80px">
          <el-row :gutter="24">
            <el-col :span="8">
              <el-form-item label="报表名称" prop="name">
                <common-input
                  v-model="form.name"
                  :maxlength="16"
                  placeholder="请输入"
                />
              </el-form-item>
            </el-col>

            <el-col :span="8">
              <el-form-item label="时间区间">
                <el-select
                  v-model="form.timeinterval"
                  placeholder="请选择"
                  clearable
                  style="width: 100%"
                >
                  <el-option
                    v-for="(item, index) in timeintervalList"
                    :key="index"
                    :label="item.name"
                    :value="item.code"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>

            <el-col :span="8">
              <el-form-item label="刷新频率" prop="frequency">
                <el-select
                  v-model="form.frequency"
                  placeholder="请选择"
                  clearable
                  style="width: 100%"
                >
                  <el-option label="无" :value="0"></el-option>
                  <el-option
                    v-for="(item, index) in frequencyList"
                    :key="index"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>

            <el-col :span="24">
              <el-form-item label="描述" prop="remark">
                <common-input v-model="form.remark" resize="none" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
      <div class="report-config-wrap">
        <div class="report-config-title-warp">
          <div class="menu-title">
            <common-group-title title="报表配置"></common-group-title>
          </div>

          <div class="config-tips">
            <span> 由左侧直接拖动报表组件至此区域内 </span>
          </div>
        </div>
        <div class="report-config">
          <div class="report-group-chart-wrap">
            <common-tree
              slot="group"
              :treeData="menuTree"
              :treeProp="treeProp"
              :searchPlaceholder="'查询组件'"
              isSlot
              searchForChildren
              :highlightCurrent="false"
            >
              <div
                style="width: 100%"
                slot-scope="{ scope }"
                @dragstart="dragStart($event, scope.data)"
                draggable="true"
              >
                <common-carousel-text
                  :content="scope.node.label"
                  :font-size="14"
                >
                </common-carousel-text>
              </div>
            </common-tree>

            <!--            <common-input-->
            <!--              v-model="componentName"-->
            <!--              :placeholder="'查询组件'"-->
            <!--              @input="search"-->
            <!--              prefix-icon="el-icon-search"-->
            <!--            ></common-input>-->
            <!--            <div class="report-group-tree-wrap">-->
            <!--              <el-tree :data="menuTree"-->
            <!--                       :props="treeProp"-->
            <!--                       :expand-on-click-node="false"-->
            <!--                       default-expand-all-->
            <!--                       :filter-node-method="filterNode"-->
            <!--                       ref="menuTree">-->

            <!--                <div style="width: 120px; height: 100%; display: flex; align-items: center"-->
            <!--                   slot-scope="{ node, data }"-->
            <!--                   @dragstart="dragStart($event,data)"-->
            <!--                   draggable="true">-->
            <!--                  <common-carousel-text-->
            <!--                    :content="node.label"-->
            <!--                    :index="node.id"-->
            <!--                    :font-size="14"-->
            <!--                  >-->
            <!--                  </common-carousel-text>-->
            <!--                </div>-->
            <!--                &lt;!&ndash;                <span class="label"&ndash;&gt;-->
            <!--                &lt;!&ndash;                      slot-scope="{ node, data }"&ndash;&gt;-->
            <!--                &lt;!&ndash;                      @dragstart="dragStart($event,data)"&ndash;&gt;-->
            <!--                &lt;!&ndash;                      draggable="true">&ndash;&gt;-->
            <!--                &lt;!&ndash;                  {{ node.label }}&ndash;&gt;-->
            <!--                &lt;!&ndash;                </span>&ndash;&gt;-->
            <!--              </el-tree>-->
            <!--            </div>-->
          </div>
          <div class="report-config-body-wrap">
            <div
              class="chart-box"
              @drop="drop"
              @dragover="dragOver"
              @dragenter="dragEnter"
            >
              <gridEchart ref="gridEchart" :boxList="boxList" />
            </div>
          </div>
        </div>
      </div>
    </div>
  </common-page>
</template>

<script>
import gridEchart from "@/components/gridEchart";
import { subgroup_tree } from "@/api/management/echart/subgroup.js";
import {
  report_add,
  report_getFrequencyList,
  report_getTimeintervalList,
  report_edit,
  report_getComponent,
} from "@/api/management/echart/report-config";

export default {
  name: "",
  components: { gridEchart },
  props: {},
  data() {
    return {
      isPersistenceLoading: false,
      sampleDataSet: {
        dimensions: [],
        source: [],
      },
      componentName: "", //菜单筛选
      menuTree: [], // 菜单树
      treeProp: {
        // 树参数
        children: "children",
        label: "name",
      },
      frequencyList: [],
      timeintervalList: [],
      dragFlag: false,
      boxList: [],
      isEdit: false,
      form: {
        frequency: "",
        name: "",
        timeinterval: null,
        remark: "",
        subjectComponentList: [],
      },
      rules: {
        frequency: [{ required: true, message: "请选择刷新频率" }],
        name: [
          {
            required: true,
            message: "请输入报表名称",
            trigger: "blur",
          },
        ],
      },
    };
  },
  // 方法
  methods: {
    edit(data) {
      this.addView = true;
      this.$nextTick(() => {
        this.form = data;
        this.isEdit = true;
        this.boxList = data.subjectComponentVoList.reduce((r, c, index) => {
          let key = `${new Date().getTime()}_${index}`;
          r.push({
            key: key,
            name: "",
            x: c.x,
            y: c.y,
            w: c.w,
            h: c.h,
            i: c.componentId,
            isError: false,
            isLoading: true,
            option: null,
          });
          return r;
        }, []);
        this.handleData();
      });
    },
    handleData() {
      this.boxList.forEach((item) => {
        this.getChartData(item.i)
          .then(({ opt, name }) => {
            item.option = opt;
            item.name = name;
            item.isLoading = false;
            item.key = `${item.i}_${new Date().getTime()}`;
          })
          .catch((err) => {
            item.isError = true;
            item.isLoading = false;
            item.key = `${item.i}_${new Date().getTime()}`;
          });
      });
    },
    submit() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          if (this.boxList.length > 0) {
            if (this.isPersistenceLoading !== true) {
              this.isPersistenceLoading = true;

              let form = { ...this.form };
              if (this.isEdit) {
                //
                form.subjectComponentList = [];
                this.boxList.forEach((item) => {
                  form.subjectComponentList.push({
                    componentId: item.i,
                    h: item.h,
                    w: item.w,
                    x: item.x,
                    y: item.y,
                    id: item.id,
                    subjectId: item.subjectId,
                  });
                });
                report_edit(form)
                  .then((res) => {
                    if (res && res.code === 200) {
                      this.$GlobalSuccessMessage("编辑成功");
                      this.$emit("refresh");
                    } else {
                      this.$GlobalErrorConfirm("编辑失败", res.msg);
                    }
                  })
                  .catch((err) => {
                    this.$GlobalErrorConfirm("编辑失败", err.msg);
                  })
                  .finally(() => {
                    this.isPersistenceLoading = false;
                  });
              } else {
                this.boxList.forEach((item) => {
                  form.subjectComponentList.push({
                    componentId: item.i,
                    h: item.h,
                    w: item.w,
                    x: item.x,
                    y: item.y,
                    parameter: JSON.stringify(item.option),
                  });
                });
                report_add(form)
                  .then((res) => {
                    if (res && res.code === 200) {
                      this.$GlobalSuccessMessage("新增成功");
                      this.$emit("refresh");
                    } else {
                      this.$GlobalErrorConfirm("新增失败", res.msg);
                    }
                  })
                  .catch((err) => {
                    this.$GlobalErrorConfirm("新增失败", err.msg);
                  })
                  .finally(() => {
                    this.isPersistenceLoading = false;
                  });
              }
            }
          } else {
            this.$GlobalErrorConfirm("请先添加组件", "最少添加一个组件");
          }
        }
      });
    },
    goBack() {
      this.$emit("back");
    },
    dragStart(e, data) {
      let flag = false; // 去除重复提交
      if (this.boxList && this.boxList.length) {
        this.boxList.map((v) => {
          if (v.i == data.id) {
            flag = true;
          }
        });
      }
      if (data.leaf && !flag) {
        this.dragFlag = true;
        let c = data.componentVo;
        e.dataTransfer.setData("componentId", c ? c.id : null);
      } else {
        this.dragFlag = false;
      }
    },
    dragEnter(e) {},
    dragOver(e) {
      if (this.dragFlag) {
        e.preventDefault();
      }
    },
    drop(e) {
      let componentId = e.dataTransfer.getData("componentId");

      this.addChart(componentId);
    },
    getTree() {
      subgroup_tree({ name: this.componentName }).then((res) => {
        if (res && res.code === 200) {
          this.menuTree = res.data;
        } else {
          this.menuTree = [];
        }
      });
    },
    addChart(id) {
      if (this.boxList.length < 12) {
        let key = `${new Date().getTime()}_${id}`;
        this.boxList.push({
          key: key,
          name: "",
          x: 0,
          y: 0,
          w: 24,
          h: 8,
          i: id,
          isLoading: true,
          option: null,
        });
        this.$nextTick(() => {
          setTimeout(() => {
            this.getChartData(id)
              .then(({ opt, name }) => {
                this.boxList.forEach((item) => {
                  if (item.key === key) {
                    item.option = opt;
                    item.name = name;
                    item.isLoading = false;
                    item.key = `${item.i}_${new Date().getTime()}`;
                  }
                });
              })
              .catch((err) => {
                this.boxList.forEach((item) => {
                  if (item.key === key) {
                    item.isError = true;
                    item.isLoading = false;
                    item.key = `${item.i}_${new Date().getTime()}`;
                  }
                });
              });
          }, 500);
        });
      } else {
        this.$confirm("最多添加12个组件!", "提示", {
          confirmButtonText: "确定",
          showCancelButton: false,
          type: "warning",
        });
      }
    },
    handleOption(list, option, mapper) {
      option.dataset = {
        dimensions: mapper.dimensions.split(","),
        source: list,
      };
      return option;
    },
    getChartData(id) {
      return new Promise((resolve, reject) => {
        report_getComponent({
          componentId: id,
          timeinterval: this.form.timeinterval,
        })
          .then((res) => {
            if (res && res.code === 200) {
              let option, mapper;
              let { name } = res.component;

              let { list } = res.data;

              let configStr = res.component.parameter;
              let optionStr = res.component.echart.parameter;

              try {
                let config = JSON.parse(configStr);
                mapper = config.mapper;
              } catch (e) {
                console.err("配置项转换异常: ", e);
              }

              try {
                option = JSON.parse(optionStr);
              } catch (e) {
                console.err("option转换异常: ", e);
              }

              if (list && option && mapper) {
                let fullOption = this.handleOption(list, option, mapper);
                resolve({
                  opt: fullOption,
                  name,
                });
              } else {
                reject();
              }
            } else {
              reject();
            }
          })
          .catch((err) => {
            reject(err);
          });
      });
    },
    /**
     * 返回
     */
    back() {
      this.$emit("back");
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    init() {
      report_getFrequencyList({}).then((res) => {
        this.frequencyList = res.data.reduce((r, c) => {
          r.push({
            label: `${c}分钟`,
            value: c,
          });
          return r;
        }, []);
      });
      report_getTimeintervalList({}).then((res) => {
        this.timeintervalList = res.data;
      });
    },
    search() {
      this.getTree();
    },
  },
  // 生命周期 - 创建完成（可以访问当前this实例）
  created() {
    this.getTree();
    this.init();
  },
  // 生命周期 - 挂载完成（可以访问DOM元素）
  mounted() {},
};
</script>
<style lang="scss" scoped>
.report-add-page {
  user-select: none;

  .report-add-page-main {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;

    .base-info-wrap {
      padding: 0 12px 12px 12px;
      box-sizing: border-box;
      height: 144px;
    }

    .report-config-wrap {
      display: flex;
      flex-direction: column;
      border-top: 1px solid #eee;
      height: calc(100% - 144px);

      .report-config-title-warp {
        height: 42px;
        padding-left: 12px;
        box-sizing: border-box;
        display: flex;
        align-items: center;

        .menu-title {
          width: 210px;
        }

        .config-tips {
          font-size: 12px;
          color: #606266;
        }
      }

      .report-config {
        display: flex;
        flex-direction: row;
        height: calc(100% - 42px);

        .report-group-chart-wrap {
          width: 209px;
          height: 100%;
          padding: 0 12px 12px 12px;
          box-sizing: border-box;
          border-right: 1px solid #eee;
          font-size: 14px;

          .report-group-tree-wrap {
            height: calc(100% - 32px - 12px);
            margin-top: 12px;
            overflow: scroll;
          }
        }

        .report-config-body-wrap {
          width: calc(100% - 210px);
          height: 100%;

          .chart-box {
            width: 100%;
            height: 100%;
          }
        }
      }
    }
  }
}
</style>
